const { Service } = require("egg");
const { Op } = require("sequelize");

class PersonCertificateService extends Service {

  async create(data) {
    return await this.ctx.model.PersonCertificate.create(data).then(res => res ? res.toJSON() : res);
  }

  async get (where) {
    return await this.ctx.model.PersonCertificate.findOne(where);

  }
  async getById(id) {
    return await this.ctx.model.PersonCertificate.findByPk(id, { raw: true });
  }


  async list({pageNum = 1, pageSize = 20, search}) {
    const offset = (pageNum - 1) * pageSize;
    let where = { isDeleted: 0 };
    if (search) {
      where = {
        ...where,
        [Op.or]: [
          { idNumber: { [Op.like]: `%${search}%` } },
          { certificateNumber: { [Op.like]: `%${search}%` } }
        ]
      };
    }
 
    const datas = await this.ctx.model.PersonCertificate.findAll({
      raw: true,
      order: [['createdAt', 'DESC']],
      limit: pageSize,
      offset: offset,
      where, 
    });
    const total = await this.ctx.model.PersonCertificate.count({ where });
    const hasNextPage = offset + pageSize < total;
    return {
      total,
      pageNum,
      pageSize,
      hasNextPage,
      sorts: datas,
    };
  }

  async update(id, updates) {
    const where = { id, isDeleted: 0 };
    return await this.ctx.model.PersonCertificate.update(updates, { where });
  }

  async delete(id) {
    const updates = { isDeleted: 1 };
    return await this.ctx.model.PersonCertificate.update(updates, { where: { id } });
  }

  async findNextCertificate(rules) {
    const { ctx } = this;
    let certificateRules = [];
    try {
      certificateRules = JSON.parse(rules)
    } catch (error) { }

    const [first, format, len] = certificateRules;
    const prefix = format === 'none' ? '' : ctx.helper.formatDate(new Date(), format)
    const certificateName = first + prefix;

    const miniId = certificateName + '0'.repeat(len - 1) + '1';
    const maxId = certificateName + '9'.repeat(len)

    try {
        const foundCertificate = await this.ctx.model.PersonCertificate.findOne({
            where: {
                certificateNumber: {
                    [Op.between]: [miniId, maxId]
                }
            },
            order: [['certificateNumber', 'DESC']],
            limit: 1
        });
        if (!foundCertificate) {
            return miniId;
        }

        const foundCertificateNumber = foundCertificate.certificateNumber;
        const numberPart = parseInt(foundCertificateNumber.substring(certificateName.length), 10);
        const incrementedNumber = numberPart + 1;

        const formattedNumber = incrementedNumber.toString().padStart(len, '0');
        const newCertificateNumber = `${certificateName}${formattedNumber}`;
        if (newCertificateNumber > maxId) {
            throw new Error('证书编号已满，不能给该颁发证书');
        }
        return newCertificateNumber;
    } catch (error) {
        console.error('Error while fetching the certificate:', error);
        throw error;
    }
  }

  async findExistCertificate(certificateNumber) {
    const where = { certificateNumber, isDeleted: 0 };
    return await this.ctx.model.PersonCertificate.findOne({ where });
  }
}

module.exports = PersonCertificateService;